home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #5 / Amiga Plus CD - 2000 - No. 5.iso / Tools / Dev / fpc / demos / mapmaker.pas < prev    next >
Pascal/Delphi Source File  |  2000-01-01  |  10KB  |  387 lines

  1. Program MapMaker;
  2.  
  3. uses Exec, graphics, Intuition, Utility,vartags;
  4.  
  5.  
  6. {
  7.     Patrick Quaid.
  8.     This program just draws a blocky map from straight overhead,
  9. then repeatedly splits each block into four parts and adjusts the
  10. elevation of each of the parts until it gets down to one pixel per
  11. block.  It ends up looking something like a terrain map.  It's kind
  12. of a fractal thing, but not too much.  Some program a long time ago
  13. inspired this, but I apologize for forgetting which one.  As I
  14. recall, that program was derived from Chris Gray's sc.
  15.     Once upon a time I was thinking about writing an overblown
  16. strategic conquest game, and this was the first stab at a map
  17. maker.  The maps it produces look nifty, but have no sense of
  18. geology so they're really not too useful for a game.
  19.     When the map is finished, press the left button inside the
  20. window somewhere and the program will go away.
  21. }
  22.  
  23. {
  24.     Changed the source to 2.0+.
  25.     12 May 1998.
  26.  
  27.     Translated to FPC. This was one of the first
  28.     program I tried with fpc, just to check that
  29.     the amiga units worked.
  30.     08 Aug 1998.
  31.  
  32.     Changed to use TAGS.
  33.     01 Nov 1998.
  34.  
  35.     nils.sjoholm@mailbox.swipnet.se
  36. }
  37.  
  38. const
  39.     MinX = 0;
  40.     MaxX = 320;
  41.     MinY = 0;
  42.     MaxY = 200;
  43.  
  44. type
  45.     MapArray = array [MinX .. MaxX - 1, MinY .. MaxY - 1] of Longint;
  46.  
  47. VAR
  48.     average,x,y,
  49.     nextx,nexty,count1,
  50.     skip,level    : Longint;
  51.     rp            : pRastPort;
  52.     vp            : Pointer;
  53.     s             : pScreen;
  54.     w             : pWindow;
  55.     m             : pMessage;
  56.     Map           : MapArray;
  57.     Quit          : Boolean;
  58.     i             : Longint;
  59.  
  60. Function FixX(x : Longint): Longint;
  61. begin
  62.     if x < 0 then
  63.     FixX := x + MaxX
  64.     else if x >= MaxX then
  65.     FixX := x mod MaxX
  66.     else
  67.     FixX := x;
  68. end;
  69.  
  70. Function FixY(y : Longint) : Longint;
  71. begin
  72.     if x < 0 then
  73.     FixY := y + MaxY
  74.     else if x >= MaxY then
  75.     FixY := y mod MaxY
  76.     else
  77.     FixY := y;
  78. end;
  79.  
  80. Procedure DrawMap;
  81. begin
  82.     if skip = 1 then begin
  83.     for x := MinX to MaxX - 1 do begin
  84.         for y := MinY to MaxY - 1 DO begin
  85.         if Map[x,y] < 100 then begin
  86.             SetAPen(rp, 0);
  87.             i := WritePixel(rp, x, y)
  88.         end else begin
  89.             average := (Map[x,y] - 100) DIV 6 + 1;
  90.             if average > 15 then
  91.             average := 15;
  92.             SetAPen(rp, average);
  93.             i := WritePixel(rp, x, y)
  94.         end
  95.         end
  96.     end
  97.    end else begin
  98.     x := MinX;
  99.     while x < MaxX do begin
  100.         y := MinY;
  101.         while y < MaxY do begin
  102.         if Map[x,y] < 100 then begin
  103.             SetAPen(rp, 0);
  104.             RectFill(rp,x,y,x + skip - 1,y + skip - 1)
  105.         end else begin
  106.             average := (Map[x,y] - 100) DIV 6 + 1;
  107.             if average > 15 then
  108.             average := 15;
  109.             SetAPen(rp,average);
  110.             RectFill(rp,x,y,x + skip - 1,y + skip - 1);
  111.         end;
  112.         y := y + skip;
  113.         end;
  114.         x := x + skip;
  115.     end;
  116.     end;
  117. end;
  118.  
  119. Function Min(x,y : Longint) : Longint;
  120. begin
  121.     if x < y then
  122.     Min := x
  123.     else
  124.     Min := y;
  125. end;
  126.  
  127. Function Max(x,y : Longint) : Longint;
  128. begin
  129.     if x > y then
  130.     Max := x
  131.     else
  132.     Max := y;
  133. end;
  134.  
  135.  
  136. Function Height(x,y : Longint) : Longint;
  137. begin
  138.     Height := Map[x,y] div 32;
  139. end;
  140.  
  141. Procedure ChangeDelta(var d : Longint);
  142. begin
  143.     case Random(100) of
  144.       51..75   : if d < 1 then
  145.              Inc(d);
  146.       76..100  : if d > -1 then
  147.              Dec(d);
  148.     end;
  149. end;
  150.  
  151. Procedure MakeRivers;
  152. var
  153.     i    : Longint;
  154.     x,y,
  155.     dx,dy  : Longint;
  156.     OK   : Boolean;
  157.     LastHeight : Longint;
  158.     count1      : Longint;
  159.     cx,cy      : Longint;
  160.     Search     : Longint;
  161.     CheckHeight : Longint;
  162. begin
  163.     SetAPen(rp, 16);
  164.  
  165.     for cx := 0 to 319 do begin
  166.     for cy := 0 to 199 do begin
  167.         if (Map[cx,cy] > 153) and (Map[cx,cy] < 162) and
  168.            (Random(100) < 3) then begin
  169.  
  170.         x := cx;
  171.         y := cy;
  172.  
  173.         dx := 0;
  174.         dy := 0;
  175.         while (dx = 0) and (dy = 0) do begin
  176.             dx := Random(2) - 1;
  177.             dy := Random(2) - 1;
  178.         end;
  179.  
  180.         OK := True;
  181.  
  182.         count1 := 0;
  183.         while OK do begin
  184.             LastHeight := Map[x,y]; { Height(x,y); }
  185.             Map[x,y] := 0;
  186.             i := WritePixel(rp, x, y);
  187.  
  188.             CheckHeight := -6;
  189.             Search := 0;
  190.             repeat
  191.                 repeat
  192.                 ChangeDelta(dx);
  193.                 ChangeDelta(dy);
  194.                 until (dx <> 0) or (dy <> 0);
  195.             Inc(Search);
  196.             if (Map[FixX(x + dx), FixY(y + dy)] > 0) and
  197.                          {  (Height(FixX(x + dx), FixY(y + dy)) < CheckHeight) then begin }
  198.                (Map[FixX(x + dx), FixY(y + dy)] < (LastHeight + CheckHeight)) then begin
  199.                 x := FixX(x + dx);
  200.                 y := FixY(y + dy);
  201.                 Search := 0;
  202.             end else if Search > 200 then begin
  203.                 if CheckHeight < 6 then begin
  204.                 Inc(CheckHeight,2);
  205.                 Search := 1;
  206.                 end else begin
  207.                 Search := 0;
  208.                 OK := False;
  209.                 end;
  210.             end;
  211.             until Search = 0;
  212.  
  213.             Inc(count1);
  214.             if count1 > 150 then
  215.             OK := False;
  216.             if Map[x,y] < 100 then
  217.             OK := False;
  218.         end;
  219.         end;
  220.     end;
  221.     end;
  222. end;
  223.  
  224. Procedure MakeMap;
  225. begin
  226.  
  227.     rp:= w^.RPort;
  228.     vp:= ViewPortAddress(w);
  229.  
  230.     SetRGB4(vp, 0, 0, 0, 12); { Ocean Blue }
  231.     SetRGB4(vp, 1, 1, 1, 0);
  232.     SetRGB4(vp, 2, 0, 3, 0);
  233.     SetRGB4(vp, 3, 0, 4, 0); { Dark Green }
  234.     SetRGB4(vp, 4, 0, 5, 0);
  235.     SetRGB4(vp, 5, 1, 6, 0);
  236.     SetRGB4(vp, 6, 2, 8, 0); { Medium Green }
  237.     SetRGB4(vp, 7, 4, 10, 0);
  238.     SetRGB4(vp, 8, 6, 10, 0);
  239.     SetRGB4(vp, 9, 9, 9, 0); { Brown }
  240.     SetRGB4(vp, 10, 8, 8, 0);
  241.     SetRGB4(vp, 11, 7, 7, 0); { Dark Brown }
  242.     SetRGB4(vp, 12, 10, 10, 0); { Dark Grey }
  243.     SetRGB4(vp, 13, 10, 10, 10);
  244.     SetRGB4(vp, 14, 12, 12, 12);
  245.     SetRGB4(vp, 15, 14, 14, 15); { White }
  246.     SetRGB4(vp, 16, 0, 0, 10);   { River blue }
  247.  
  248.     Randomize; { Seed the Random Number Generator }
  249.  
  250.     level := 7;
  251.     skip  := 16;
  252.  
  253.     y := MinY;
  254.     while y < MaxY do begin
  255.     x := MinX;
  256.     while x < MaxX do begin
  257.         Map[x,y] := Random(220);
  258.         x := x + skip;
  259.     end;
  260.     y := y + skip;
  261.     end;
  262.  
  263.     DrawMap;
  264.  
  265.     for level := 2 to 5 do begin
  266.     skip := skip DIV 2;
  267.     y := MinY;
  268.     while y < MaxY do begin
  269.         if (y MOD (2*skip)) = 0 then
  270.         nexty := skip * 2
  271.         else
  272.         nexty:=skip;
  273.         x := MinX;
  274.         while x < MaxX do begin
  275.         if (x MOD (2*skip)) = 0 then
  276.             nextx := skip * 2
  277.         else
  278.             nextx := skip;
  279.         if (nextx = skip * 2) AND (nexty = skip * 2) then begin
  280.             average := Map[x,y] * 5;
  281.             count1 := 9;
  282.         end else begin
  283.             average := 0;
  284.             count1 := 4;
  285.         end;
  286.         if (nextx = skip * 2) then begin
  287.             average := average + Map[x,FixY(y - skip)];
  288.             average := average + Map[x,FixY(y + nexty)];
  289.             count1 := count1 + 2;
  290.         end;
  291.         if (nexty = skip * 2) then begin
  292.             average := average + Map[FixX(x - skip),y];
  293.             average := average + Map[FixX(x + nextx),y];
  294.             count1 := count1 + 2;
  295.         end;
  296.         average := average + Map[FixX(x-skip),FixY(y-skip)]
  297.                    + Map[FixX(x-nextx),FixY(y+nexty)]
  298.                    + Map[FixX(x+skip),FixY(y-skip)]
  299.                    + Map[FixX(x+nextx),FixY(y+nexty)];
  300.         average := (average DIV count1) +
  301.                 (Random(4) - 2) * (9 - level);
  302.         case Average of
  303.           150..255 : Average := Average + 2;
  304.           100..149 : Inc(Average);
  305.         else
  306.             Average := Average - 3;
  307.         end;
  308.         if average < 0 then
  309.             average := 0;
  310.         if average > 220 then
  311.             average := 220;
  312.         Map[x,y] := average;
  313.  
  314.         x := x + skip;
  315.         end;
  316.         m := GetMsg(w^.UserPort);
  317.         if m <> Nil then begin
  318.         Quit := True;
  319.         Exit;
  320.         end;
  321.         y := y + skip;
  322.     end;
  323.     DrawMap;
  324.     end;
  325.     MakeRivers;
  326. end;
  327.  
  328. begin
  329.     GfxBase := OpenLibrary(GRAPHICSNAME,0);
  330.     if GfxBase <> nil then begin
  331.  
  332.     s := OpenScreenTagList(NIL, TAGS(
  333.                            SA_Left,      0,
  334.                            SA_Top,       0,
  335.                            SA_Width,     320,
  336.                            SA_Height,    200,
  337.                            SA_Depth,     5,
  338.                            SA_DetailPen, 3,
  339.                            SA_BlockPen,  2,
  340.                            SA_Type,      CUSTOMSCREEN_f,
  341.                            TAG_END));
  342.  
  343.     
  344.  
  345.     if s <> NIL then begin
  346.  
  347.         w := OpenWindowTagList(NIL, TAGS(
  348.         WA_IDCMP,        IDCMP_MOUSEBUTTONS,
  349.         WA_Left,         MinX,
  350.         WA_Top,          MinY,
  351.         WA_Width,        MaxX,
  352.         WA_Height,       MaxY,
  353.         WA_MinWidth,     50,
  354.         WA_MinHeight,    20,
  355.         WA_Borderless,   ltrue,
  356.         WA_BackDrop,     ltrue,
  357.         WA_SmartRefresh, ltrue,
  358.         WA_Activate,     ltrue,
  359.         WA_CustomScreen, longint(s),
  360.         TAG_END));
  361.  
  362.         
  363.  
  364.         IF w <> NIL THEN begin
  365.         Quit := False;
  366.         ShowTitle(s, 0);
  367.         MakeMap;
  368.         if not Quit then
  369.             m := WaitPort(w^.UserPort);
  370.         Forbid;
  371.         repeat
  372.             m := GetMsg(w^.UserPort);
  373.         until m = nil;
  374.         CloseWindow(w);
  375.         Permit;
  376.         end else
  377.         writeln('Could not open the window.');
  378.         CloseScreen(s);
  379.     end else
  380.         writeln('Could not open the screen.');
  381.     CloseLibrary(GfxBase);
  382.     end else writeln('no graphics.library');
  383. end.
  384.  
  385.  
  386.  
  387.